package com.itheima.springboot_reggie.web;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.springboot_reggie.common.R;
import com.itheima.springboot_reggie.emtity.Employee;
import com.itheima.springboot_reggie.service.IEmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;

@Slf4j           //想打印日志需要配置此注解 用lombok提供的日志输出方式，未来不要再用System.out.println()
@RestController
@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    IEmployeeService employeeService;

    @PostMapping("/login")  // 需求分析时, 我们看到前端发起的请求为post请求, 所以服务端需要使用注解 @PostMapping
    public R<Employee> checkLogin(@RequestBody Employee employee, HttpServletRequest request){ //请求数据放到了请求体里面，封装成jason,用@RequestBody接收
        log.info("登录校验,用户信息{}",employee);

        //实现登录业务
        //1.获取用户名、密码：Employee对象接收数据
        String username = employee.getUsername();
        //2.根据用户名查询用户信息： select * from Employee where username=?

        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();//创建lambda条件构建器
       wrapper.eq(Employee::getUsername, username); //employee.getUsername()，上面的请求体封装了各项参数在employee中

        Employee queryEmp = employeeService.getOne(wrapper);//先查下用户名存不存在

        //判断：查询不到，返回登录失败
        if (queryEmp == null){
                return R.error("用户名不存在");

        }

        //3.如果查询到了，比对密码是否正确（用户名输入的密码加密后和数据库的密码进行比对）
        String pwd = DigestUtils.md5DigestAsHex(employee.getPassword().getBytes());
        //判断：比对失败，返回登录失败
        if (!pwd.equals(queryEmp.getPassword())){ //用户输入的加密的pwd密码和数据库查到的密码进行比较
            return R.error("密码错误");
        }

        //5.用户状态正常，登录成功。

        //4.比对成功，说明用户名和密码正确
        //判断用户是否禁用 （status：禁用：0，正常：1）

        if (queryEmp.getStatus()==0){
            return R.error("员工被禁用");
        }

           //5.1存用户信息（只存用户的id）到 session
                     // 怎么拿session对象呢，利用框架的特性，你需要什么对象，容器有的都会给你（）
                     //  在 public R checkLogin(@RequestBody Employee employee)括号里添加 HttpServletRequest request
                     // 现在只需要填写 HttpSession session

        request.getSession().setAttribute("employee",queryEmp.getId());
           //5.2 返回响应结果
        return R.success(queryEmp);//将当前查到的员工信息放到里面
    }


    /**
     *      后台系统退出登录
     */
    @PostMapping("/logout")
    public R<String> logout(HttpServletRequest request ){
        /**
         * 客户端浏览器发出的请求被封装成为一个HttpServletRequest对象,对象包含了客户端请求信息包括请求的地址，
         * 请求的参数，提交的数据，上传的文件客户端的ip甚至客户端操作系统都包含在其内。
         * HttpServletResponse继承了ServletResponse接口，并提供了与Http协议有关的方法，
         * 这些方法的主要功能是设置HTTP状态码和管理Cookie。
         */

        // 销毁,清除 session 中的所有信息
        request.getSession().invalidate();

        return R.success("退出成功");
    }
   /*
    @PostMapping("/logout")
    public R addEmp(HttpSession session){
        //清空session
        session.removeAttribute("emp");
        return R.success("退出成功")；//code=1,退出成功，前台自动跳转到登录页面，后台要做的就是把session清空
    }*/



    /**
     *  新增员工  添加
     */
    @PostMapping
    public R<String> add(@RequestBody Employee employee){ //成功返回1，失败0
        log.info("employee:{}",employee);
//        long id =Thread.currentThread().getId();
//        log.info("add************************当前操作的线程的id:{]",id);

        // 添加员工时，下面几个设置不能为空
        //设置初始密码12345，需要进行md5加密处理    生成默认的密码
        employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
//        employee.setCreateTime(LocalDateTime.now());  //手动员工创建时间
//        employee.setUpdateTime(LocalDateTime.now());  //手动员工更新时间

//        employee.setCreateUser(1l);                  //手动创建元员工
//        employee.setUpdateUser(1l);                  //手动更新员工

        //添加用户信息
       employeeService.save(employee);
        return R.success("新增员工成功");
    }
    /**
     *   分页查询
     *   参数 ：@Param page       当前页码
     *         @Param pageSize   每页展示记录数
     *        @param name        员工姓名 - 可选参数
     */
    /*@GetMapping("/page")
    public R<Page> queryPage(Integer pageSize,Integer page, String name){

        //构建分页构造器
        Page page1 = new Page(page,pageSize);

        //创建条件构造器
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();

        //添加过滤条件
        queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);
        //添加排序条件
        queryWrapper.orderByDesc(Employee::getUpdateTime);
        //执行查询
        employeeService.page(page1,queryWrapper);
        return R.success(page1);
    }*/

    /**
     *    分页+条件
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(String page,String pageSize,String name){
        log.info("page employee:{},{},{}",page,pageSize,name);
        //1.构建条件构建器和分页对象
        Page<Employee> pageCondition = new Page<>(Integer.parseInt(page),Integer.parseInt(pageSize));//limit (page-1)*pageSize，pageSize
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(name!=null && name!="",Employee::getName,name);//模糊查询时生效：name like %name 数值%

        //2.查询
        employeeService.page(pageCondition,wrapper);
        return R.success(pageCondition);


    }


    /**
     *   修改员工状态 -- 更新员工的信息和修改员工的状态使用的是同一个api
     * @Param  employee
     */
    @PutMapping
    public  R updateStatusEmp(@RequestBody Employee employee,HttpSession session){

        //1.修改员工数据 ： 从session中获取员工id
           // 怎么拿session对象呢，利用框架的特性，你需要什么对象，容器有的都会给你（）在上面得方法体里加上HttpSession session
        //进一步封装需要更新的employee实体对象
        //获取用户信息
//        Long empId = (long)session.getAttribute("employee");
//        employee.setUpdateUser(empId); //设置更新用户的id

        //2.修改员工数据 update_time   记录更新时间
 //       employee.setUpdateTime(LocalDateTime.now());//设置更新时间

        //3.调用业务层修改 、更新员工信息 updateById()
        employeeService.updateById(employee);

        return R.success("更新成功");
    }
    /**
     *  更新员工信息-- 先查询后更新(更新和修改状态使用同一个接口)
     *   @param  id
     */
    //先查询，后更新
    @GetMapping("/{id}")   //id若不加{}占位符，就是请求路径，加了{id}就是请求参数，比如网页上where id = 几
 public R <Employee> queryOneById(@PathVariable Long id){
        log.info("queryEmp employee:{}",id);
       //查询员工信息
        Employee id1 = employeeService.getById(id);
        if (id1==null){

            return R.error("没有查到对应的id信息");
        }
        //否则 id1 不等于null，那么返回成功
        return R.success(id1);
    }

}
/** 到mp官网， 自动填充功能 注解填充字段@TableField（...fill= FieldFill.INSERT）
 *  自定义实现类  MyMetaObjectHandler
 *    提供了一个fill属性，未来在进行添加和更新的时候，mybatisPlus就会检查当前的字段
 *    有没有添加这个  @TableField 注解，加了这个注解就会自动去查找这个自动填充处理器类
 *    这个类要交给spring容器管理，未来才能从容器里拿到这个自动填充工具去帮我们填充指定的字段数据
 步骤一： 找到实体对象，在你需要填充的字段上面加上 注解 @TableField（fill= FieldFill.INSERT）
 *                                             @TableField（fill= FieldFill.INSERT_UPDATE）
 *    步骤二：配置一个自动填充处理器  MyMetaObjectHandler
 *           在官网上复制下自定义实现类，在common报下创建这个实现类 ，需要加上@Component注解
 *           因为当前自动填充的工具类，需要交给spring容器管理
 */